<template>
  <div>
    <button @click="handleSendGenerate">生成</button>
  </div>
  <div class="_container" ref="containerRef" style="position: relative;">
    <canvas ref="pdfCanvas" style="width: 100%; height: 100%;"></canvas>
    <canvas ref="overlayCanvas" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;z-index:999;"
      @mousedown="startDrawing" @mousemove="draw" @mouseup="endDrawing"></canvas>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, reactive } from 'vue'
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist'

import * as PdfWorker from 'pdfjs-dist/build/pdf.worker.mjs'
  ; (window as any).PdfWorker = PdfWorker

// GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@4.3.136/build/pdf.worker.min.mjs'


const pdfCanvas = ref<HTMLCanvasElement>()
const overlayCanvas = ref<HTMLCanvasElement>()
const pdfURL = ref<string>('/pdfs/example.pdf')
// pdf文档对象
const pdfDoc = ref()
// PDF总页数
const pageNumbs = ref(0)
// 记录页面宽高
const width = ref(0)
const height = ref(0)
// PAGE对象
let pagePDfDoc: any

// 会自
const rectangles = reactive<Array<any>>([])
let isDrawing = false
let startX = 0
let startY = 0

/**
 * 加载PDF
 */
const loadPdf = async () => {
  try {
    const loadingTask = getDocument(pdfURL.value)
    const pageObject = await loadingTask.promise
    pdfDoc.value = pageObject

    if (!pdfDoc.value) {
      throw new Error('Failed to load PDF document.')
    }
    pagePDfDoc = pageObject
    pageNumbs.value = await pdfDoc.value.numPages
    console.log(`PDF 加载: ${pageNumbs.value} 页`)
  } catch (error) {
    console.error('加载PDF失败:', error)
  }
}

/**
 * 渲染PDF页面
 */
const pageWidthVal = ref(0)
const pageHeightVal = ref(0)
const renderPage = async (pageNum = 1) => {

  const page = await pagePDfDoc.getPage(pageNum)
  // 适配区域
  const canvas = pdfCanvas.value!
  const overlay = overlayCanvas.value!;
  const ctx = canvas.getContext('2d')

  // 获取页面比率
  const ratio = getDatio(ctx!)
  // 计算内容区放大比例
  const dialogWidth = canvas.offsetWidth
  const pageWidth = page.view[2] * ratio
  pageWidthVal.value = page.view[2]
  pageHeightVal.value = page.view[3]

  const scale = dialogWidth / pageWidth
  console.log(`PDF 缩放: ${scale}`)

  // 视图区域
  const viewport = page.getViewport({ scale })

  width.value = viewport.width * ratio
  height.value = viewport.height * ratio

  canvas.width = width.value
  canvas.height = height.value

  overlay.width = width.value;
  overlay.height = height.value;


  // 设置缩放率
  ctx?.setTransform(ratio, 0, 0, ratio, 0, 0)

  // 渲染上下文
  const renderContext = {
    canvasContext: ctx,
    viewport: viewport
  }

  await page.render(renderContext)
  drawAllRectangles()
}


/**
 * 计算角度
 */
const getDatio = (ctx: CanvasRenderingContext2D) => {
  const dpr = window.devicePixelRatio || 1
  // @ts-ignore
  let bsr = ctx.webkitBackingStorePixelRatio ||
    // @ts-ignore
    ctx.mozBackingStorePixelRatio ||
    // @ts-ignore
    ctx.msBackingStorePixelRatio ||
    // @ts-ignore
    ctx.oBackingStorePixelRatio ||
    // @ts-ignore
    ctx.backingStorePixelRatio ||
    1
  return dpr / bsr
}

const startDrawing = (event: MouseEvent) => {
  isDrawing = true
  startX = event.offsetX
  startY = event.offsetY
}

const draw = (event: MouseEvent) => {
  if (!isDrawing) return
  const ctx = overlayCanvas.value!.getContext('2d')
  ctx?.clearRect(0, 0, overlayCanvas.value!.width, overlayCanvas.value!.height)
  drawAllRectangles()
  const currentX = event.offsetX
  const currentY = event.offsetY
  const width = currentX - startX
  const height = currentY - startY
  ctx!.strokeStyle = 'rgb(228, 228, 228)'
  ctx!.lineWidth = 2
  ctx?.strokeRect(startX, startY, width, height)
}

const endDrawing = async (event: MouseEvent) => {
  if (!isDrawing) return
  isDrawing = false
  const fieldName = prompt('请输入字段名')
  if (fieldName) {
    rectangles.push({
      x: startX,
      y: startY,
      width: event.offsetX - startX,
      height: event.offsetY - startY,
      fieldName
    })
    drawAllRectangles()
  }
}

// 渲染所有区域
const drawAllRectangles = () => {
  const ctx = overlayCanvas.value!.getContext('2d');
  ctx?.clearRect(0, 0, overlayCanvas.value!.width, overlayCanvas.value!.height);
  rectangles.forEach(rect => {
    ctx!.strokeStyle = 'rgb(0, 0, 0)';

    ctx!.lineWidth = 4;
    ctx!.strokeRect(rect.x, rect.y, rect.width, rect.height);
    ctx!.fillStyle = 'rgb(221, 228, 255)';
    ctx!.fillRect(rect.x, rect.y, rect.width, rect.height)
    ctx!.font = '20px Arial';
    ctx!.textBaseline = 'middle'
    ctx!.fillStyle = 'rgb(0, 0, 0)'

    ctx!.fillText(rect.fieldName, rect.x + rect.width / 2, rect.y + 20, rect.width); // 修正文本位置，以便不会超出矩形
  });


};


const handleSendGenerate = async () => {
  const pdfPageWidth = pageWidthVal.value;  // PDF 页面的宽度
  const pdfPageHeight = pageHeightVal.value;  // PDF 页面的高度
  const scaleRatioX = pdfPageWidth / overlayCanvas.value!.offsetWidth;
  const scaleRatioY = pdfPageHeight / overlayCanvas.value!.offsetHeight;

  const scaledRectangles = rectangles.map(rect => ({
    x: rect.x * scaleRatioX,
    y: (overlayCanvas.value!.offsetHeight - rect.y - rect.height) * scaleRatioY, // 转换为 PDF 坐标系
    width: rect.width * scaleRatioX,
    height: rect.height * scaleRatioY,
    fieldName: rect.fieldName
  }));

  fetch('/api/generate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      rectangles: scaledRectangles,
    })
  }).then(res => res.json()).then(data => {
    console.log(data)
  })
}






onMounted(async () => {
  await loadPdf()
  await renderPage(1)
})




</script>